"""
FastAPI 主应用模块
提供 Web API 服务的核心配置、中间件和路由定义
"""
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from tortoise.contrib.fastapi import register_tortoise
from tortoise.exceptions import DBConnectionError
import logging
import time
import traceback
from app.logger_setup import LoggerSetup, LogConfig
from app.config import settings
from app.routers import api_router
from typing import Callable, Awaitable
from starlette.middleware.base import BaseHTTPMiddleware
import os
from app.utils.db_utils import execute_sql_file

class RequestLoggingMiddleware(BaseHTTPMiddleware):
    """请求日志中间件"""
    
    async def dispatch(
        self, request: Request, call_next: Callable[[Request], Awaitable[JSONResponse]]
    ) -> JSONResponse:
        # 跳过特定路径的日志记录
        if request.url.path in ["/health", "/metrics", "/DevMgmt/DiscoveryTree.xml"]:
            return await call_next(request)
            
        start_time = time.time()
        logger = logging.getLogger(__name__)
        
        try:
            logger.info(
                f"开始处理请求 - Method: {request.method} "
                f"Path: {request.url.path} "
                f"Client: {request.client.host if request.client else 'Unknown'}"
            )
            
            response = await call_next(request)
            
            process_time = (time.time() - start_time) * 1000
            logger.info(
                f"请求处理完成 - Status: {response.status_code} "
                f"Processing Time: {process_time:.2f}ms"
            )
            
            return response
            
        except Exception as e:
            logger.error(
                f"请求处理异常:\n"
                f"URL: {request.url}\n"
                f"Error: {str(e)}\n"
                f"Traceback: {traceback.format_exc()}"
            )
            return JSONResponse(
                status_code=500,
                content={"detail": "Internal Server Error"}
            )

def setup_middlewares(app: FastAPI) -> None:
    """配置中间件"""
    # CORS中间件
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],  # 在生产环境中应该指定具体的源
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
    
    # 日志中间件
    app.add_middleware(RequestLoggingMiddleware)

def setup_exception_handlers(app: FastAPI, logger: logging.Logger) -> None:
    """配置异常处理器"""
    @app.exception_handler(Exception)
    async def global_exception_handler(request: Request, exc: Exception):
        logger.error(f"Unhandled exception: {exc}", exc_info=True)
        
        if isinstance(exc, DBConnectionError):
            return JSONResponse(
                status_code=500,
                content={"detail": "Database connection failed"},
            )
        
        return JSONResponse(
            status_code=500,
            content={
                "detail": "Internal Server Error",
                "message": str(exc) if settings.DEBUG else "An unexpected error occurred"
            }
        )

def setup_database(app: FastAPI) -> None:
    """
    配置数据库连接
    
    Args:
        app: FastAPI 应用实例
        
    Note:
        - generate_schemas=False 禁用自动生成表结构
        - 表结构应通过数据库迁移工具管理
    """
    register_tortoise(
        app,
        config={
            "connections": {
                "default": {
                    "engine": "tortoise.backends.mysql",
                    "credentials": {
                        "host": settings.DB_HOST,
                        "port": settings.DB_PORT,
                        "user": settings.DB_USER,
                        "password": settings.DB_PASSWORD,
                        "database": settings.DB_NAME,
                        "charset": "utf8mb4",
                        "sql_mode": "STRICT_TRANS_TABLES",
                    }
                }
            },
            "apps": {
                "models": {
                    "models": [
                        "app.models.warehouse_models",
                        "app.models.goods_models",
                        "app.models.warehouse_goods_models"
                    ],
                    "default_connection": "default",
                }
            },
        },
        generate_schemas=False,  # 禁用自动生成表结构
        add_exception_handlers=True,
    )

def create_app() -> FastAPI:
    """创建并配置FastAPI应用"""
    app = FastAPI(
        title="Inventory Management System",
        description="FastAPI based inventory management system",
        version="1.0.0",
        docs_url="/docs",
        redoc_url="/redoc",
        openapi_url="/openapi.json"
    )
    
    # 配置日志
    log_config = LogConfig(
        log_file="logs/app.log",
        log_level=logging.DEBUG if settings.DEBUG else logging.INFO,
        backup_count=7,
        log_to_console=True
    )
    logger_setup = LoggerSetup(log_config)
    logger = logger_setup.initialize_logger()

    # 配置中间件
    setup_middlewares(app)

    # 注册路由组
    app.include_router(api_router)

    # 注册异常处理器
    setup_exception_handlers(app, logger)

    # 健康检查端点
    @app.get("/health", tags=["Health"])
    async def health_check():
        """健康检查端点"""
        return {
            "status": "healthy",
            "timestamp": time.time(),
            "version": app.version,
            "environment": settings.ENV
        }

    # 配置数据库
    setup_database(app)

    async def init_db():
        """初始化数据库"""
        sql_file = os.path.join(os.path.dirname(__file__), 'sql', 'create_user_tables.sql')
        await execute_sql_file(sql_file)

    @app.on_event("startup")
    async def startup_event():
        await init_db()

    return app

# 创建应用实例
app = create_app()
